package capricornus.actor
{
	import capricornus.actor.attribute.ActorAttribute;
	import capricornus.actor.controller.ActorComponentController;
	import capricornus.actor.controller.ActorEffectController;
	import capricornus.actor.controller.ActorImageController;
	import capricornus.actor.controller.ActorMoveController;
	import capricornus.actor.controller.ActorStunController;
	import capricornus.actor.controller.ActorTrackController;
	import capricornus.actor.events.ActorAttributeEvent;
	import capricornus.actor.events.ActorEvent;
	import capricornus.actor.interactive.ActorInteractiveController;
	import capricornus.actor.utils.ActionType;
	import capricornus.scene.AbstractScene;
	import capricornus.scene.SceneManager;
	
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.Sprite;
	
	[Event(name="actorRefresh", type="capricornus.actor.events.ActorEvent")]
	public class Actor extends Sprite
	{
		/**
		 * 是否激活，只有激活的actor才会刷新 
		 */		
		protected var _isActivate:Boolean = false;
		
		/**
		 * 是否隐藏 
		 */		
		protected var _isHide:Boolean = false;
		
		/**
		 * 属性 
		 */		
		protected var _attribute:ActorAttribute;
		
		/**
		 * 组件控制器 
		 */		
		protected var _componentController:ActorComponentController;
		/**
		 * 图像控制器 
		 */		
		protected var _imageController:ActorImageController;
		/**
		 * 移动控制器 
		 */		
		protected var _moveController:ActorMoveController;
		/**
		 * 鼠标事件控制器 
		 */		
		protected var _interactiveController:ActorInteractiveController;
		/**
		 * 眩晕控制器 
		 */		
		protected var _stunController:ActorStunController;
		/**
		 * 特效控制器 
		 */		
		protected var _effectControoler:ActorEffectController;
		/**
		 * 跟踪控制器 
		 */		
		protected var _trackController:ActorTrackController;
		
		/**
		 * 图像和组件的容器 
		 */		
		protected var _container:Sprite;
		/**
		 * Actor顶部组件层，例如：血条，名字 
		 */		
		protected var _componentLayer:Sprite;
		/**
		 * 图像层 
		 */		
		protected var _imageContainer:Sprite;
		/**
		 * 特效层 
		 */		
		protected var _effectLayer:Sprite;
		
		/**
		 * 相当于parent 
		 */		
		private var _owner:DisplayObjectContainer;
		/**
		 * 所在场景 
		 */		
		protected var _scene:AbstractScene = null;
		
		public function Actor()
		{
			super();
			init();
		}
		
		private function init():void
		{
			this.mouseChildren = false;
			this.mouseEnabled = false;
			
			_container = new Sprite();
			_container.cacheAsBitmap = true;
			_container.mouseEnabled = false;
			addChild( _container );
			
			_imageContainer = new Sprite();
			_imageContainer.mouseChildren = false;
			_imageContainer.mouseEnabled = false;
			
			_container.addChild( _imageContainer );
			
			_componentLayer = new Sprite();
			_componentLayer.mouseEnabled = false;
			_componentLayer.mouseChildren = false;
			_container.addChild( _componentLayer );
			
			_effectLayer = new Sprite();
			_effectLayer.mouseChildren = false;
			_effectLayer.mouseEnabled = false;
			_container.addChild( _effectLayer );
			
			createAttribute();
			if( _attribute != null ) _attribute.addEventListener( ActorAttributeEvent.HP_CHANGED, onHPChanged, false, 0, true );
			createComponent();
			
			createImageController();
			createMoveController();
			createInteractiveController();
			createStunController();
			createTrackController();
		}
		
		public function destroy():void
		{
			dispatchEvent( new ActorEvent( ActorEvent.ACTOR_DESTROYED ) );
			
			deactivate();
			if( _imageController != null )
			{
				_imageController.destroy();
				_imageController = null;
			}
			if( _moveController != null )
			{
				_moveController.destroy();
				_moveController = null;
			}
			if( _componentController != null )
			{
				_componentController.destroy();
				_componentController = null;
			}
			if( _stunController != null )
			{
				_stunController.destroy();
				_stunController = null;
			}
			if( _trackController != null )
			{
				_trackController.destroy();
				_trackController = null;
			}
			if( _attribute != null )
			{
				_attribute.removeEventListener( ActorAttributeEvent.HP_CHANGED, onHPChanged );
			}
			if( parent != null )
			{
				parent.removeChild( this );
			}
		}
		
		protected function createAttribute():void
		{
			_attribute = new ActorAttribute();
		}
		
		protected function createImageController():void
		{
			_imageController = new ActorImageController( this );
		}
		
		protected function createMoveController():void
		{
			_moveController = new ActorMoveController( this );
		}
		
		protected function createInteractiveController():void
		{
			_interactiveController = new ActorInteractiveController( this );
		}
		
		protected function createComponent():void
		{
			_componentController = new ActorComponentController( this );
		}
		
		protected function createStunController():void
		{
			_stunController = new ActorStunController( this );
		}
		
		protected function createTrackController():void
		{
			_trackController = new ActorTrackController( this );
		}
		
		/**
		 * 激活 
		 * 
		 */		
		public function activate():void
		{
			if( !_isActivate )
			{
				_isActivate = true;
				ActorManager.instance.addActor( this );
			}
		}
		
		/**
		 * 取消激活 ,actor将不刷新, sleepping
		 * 
		 */		
		public function deactivate():void
		{
			if( _isActivate )
			{
				_isActivate = false;
				ActorManager.instance.removeActor( this );
			}
		}
		
		/**
		 * 超出屏幕区域的时候隐藏 
		 * @param value
		 * 
		 */		
		public function isHide( value:Boolean ):void
		{
			if( _isHide==value ) return;
			_isHide = value;
			_imageController.isHiding = _isHide;
			
			if( _isHide )
			{
				if( parent != null )
				{
					_owner.removeChild( this );
				}
			}
			else if( parent==null )
			{
				if( _owner != null ) _owner.addChild( this );
				sort( parent, this );
			}
			
			dispatchEvent( new ActorEvent( ActorEvent.SHOW_CHANGED, _isHide ) );
		}
		
		/**
		 * 站立 
		 * 
		 */		
		public function stand():void
		{
			playAction( ActionType.STAND, -1 );
		}
		
		/**
		 * 是否在隐藏中 
		 * @return 
		 * 
		 */		
		public function getIsHide():Boolean
		{
			return _isHide;
		}
		
		/**
		 * 是否激活 
		 * @return 
		 * 
		 */		
		public function get isActivate():Boolean
		{
			return _isActivate;
		}

		/**
		 * 是否还活着 
		 * @return 
		 * 
		 */		
		public function isLive():Boolean
		{
			return _attribute.hp > 0;
		}
		
		/**
		 * 总行程 
		 * @return 总行程
		 * 
		 */		
		public function get pastLength():Number
		{
			return _moveController != null ? _moveController.pastLength : 0;
		}
		
		public function get attribute():ActorAttribute
		{
			return _attribute;
		}
		
		public function get imageContainer():Sprite
		{
			return _imageContainer;
		}
		
		/**
		 * 组件层，就是人头上那些名字啊，状态啊啥的，全在这里 
		 * @return 
		 * 
		 */		
		public function get componentLayer():Sprite
		{
			return _componentLayer;
		}
		
		/**
		 * 特效层 
		 * @return 
		 * 
		 */		
		public function get effectLayer():Sprite
		{
			return _effectLayer;
		}
		
		public function get moveController():ActorMoveController
		{
			return _moveController;
		}
		
		public function get interactiveController():ActorInteractiveController
		{
			return _interactiveController;
		}
		
		/**
		 * 该Actor是否可点击，默认是true 
		 * @param value
		 * 
		 */		
		public function set interactiveEnabled( value:Boolean ):void
		{
			if(_interactiveController != null ) _interactiveController.interactiveEnabled = value;
		}
		
		public function get interactiveEnabled():Boolean
		{
			return _interactiveController != null ? _interactiveController.interactiveEnabled : true;
		}
		
		/**
		 * 组件高度 
		 * @param v
		 * 
		 */		
		public function set componentHeight( v:int ):void
		{
			_componentController.height = v;
		}
		
		/**
		 * 是否眩晕 
		 * @return 
		 * 
		 */		
		public function get stunning():Boolean
		{
			return _stunController != null ? _stunController.stunning : false;
		}
		
		/**
		 * 上一次停留的位置数组。注：请勿修改里面的值 
		 */		
		private var _arrLast:Array = new Array(2);
		/**
		 * 设置位置 
		 * @param x
		 * @param y
		 * @param sendEvent
		 * 
		 */		
		public function setLocation( x:int, y:int, sendEvent:Boolean=true ):void
		{
			_arrLast[0] = super.x;
			_arrLast[1] = super.y;
			super.x = x;
			super.y = y;
			
			sort( parent, this );
			
			if( sendEvent )
			{
				this.dispatchEvent( new ActorEvent( ActorEvent.MOVED, _arrLast ) );
			}
		}
		
		/**
		 * 跟踪actor 
		 * @param actor
		 * 
		 */		
		public function track( actor:Actor ):void
		{
			_trackController.track( actor );
		}
		
		/**
		 * 播放次数等于-1时表示不停播放
		 * 
		 * @param actionType 播放的动作
		 * @param times      播放次数
		 * @param endType    actionType动作结束后播放的动作
		 * @param endTime    结束动作的播放次数
		 * 
		 */	
		public function playAction( actionType:int, times:int=1, endType:int=ActionType.STAND, endTime:int=-1 ):void
		{
			_imageController.playAction( actionType, times, endType, endTime );
		}
		
		/**
		 * 刷新数组 
		 * @param time
		 * 
		 */		
		public function refresh( time:uint ):void
		{
			var isStunning:Boolean = false;
			if( _stunController != null )
			{
				_stunController.refresh( time );
				isStunning = _stunController.stunning;
			}
			if( _imageController != null ) _imageController.refresh( time );
			if( !isStunning && _moveController != null ) _moveController.refresh( time );
			
//			dispatchEvent( new ActorEvent( ActorEvent.ACTOR_REFRESH, time ) );
		}
		
		/**
		 * 移动，添加移动数组 
		 * @param arrPath
		 * 
		 */		
		public function addMovePath( arrPath:Array ):void
		{
			_moveController.addMovePath( arrPath );
		}
		
		/**
		 * 添加到场景 
		 * 
		 */		
		public function onAddToScene():void
		{
			_owner = parent;
			_scene = SceneManager.instance.scene;
			sort( parent, this );
		}
		
		/**
		 * 从场景中移除 
		 * 
		 */		
		public function onRemoveFromScene():void
		{
			_scene = null;
			_owner = null;
		}
		
		/**
		 * 眩晕 
		 * @param duration 眩晕时间（ms）
		 * 
		 */		
		public function stun( duration:int ):void
		{
			if( _stunController != null ) 
			{
				_stunController.start( duration );
				if( _stunController.stunning )
				{
					_imageController.playAction( ActionType.STAND, -1 );
				}
			}
		}
		
		/**
		 * 醒来。从“眩晕”、“睡眠”等状态中恢复过来 
		 * 一般要重载此函数
		 */		
		public function wakeUp():void
		{
			
		}
		
		override public function set x(value:Number):void
		{
			throw new Error("请调用setLocation设置Actor的x、y坐标！");
		}
		
		override public function set y(value:Number):void
		{
			throw new Error("请调用setLocation设置Actor的x、y坐标！");
		}
		
		/**
		 * 生命值改变 
		 * @param e
		 * 
		 */		
		private function onHPChanged( e:ActorAttributeEvent ):void
		{
			if( _attribute.hp < 1 )
			{
				destroy();
			}
		}
		
		/**
		 * 排序 
		 * @param container
		 * @param actor
		 * 
		 */		
		protected function sort( container:DisplayObjectContainer, actor:Actor ):void
		{
			if( container==null ) return;
			var len:int = container.numChildren;
			var i:int;
			var dis:DisplayObject;
			var y:int = actor.y;
			var index:int = container.getChildIndex( actor );
			var b:Boolean = true;
			var toIndex:int = index;
			
			for( i=index+1; i < len; i++ )
			{
				dis = container.getChildAt(i);
				if( dis.y < y )
				{
					b = false;
					toIndex = i;
				}
				else break;
			}
			if( b )
			{
				for( i = index - 1; i > -1; i-- )
				{
					dis = container.getChildAt(i);
					if( dis.y > y )
					{
						toIndex = i;
					}
					else break;
				}
			}
			
			if( index != toIndex )
			{
				container.setChildIndex( actor, toIndex );
			}
		}
	}
}













